from sqlalchemy import create_engine, MetaData, inspect
from sqlalchemy.orm import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session
from settings import CommonConfig, BASE_URL

"""
迁移数据库文档：https://www.cnblogs.com/gcxblogs/p/14979282.html
SQLAlchemy 1.4/2.0教程 ： https://www.osgeo.cn/sqlalchemy/tutorial/index.html
官方文档：https://dormousehole.readthedocs.io/en/latest/patterns/sqlalchemy.html
https://blog.csdn.net/weixin_42474540/article/details/105100677
关于线程池安全：
session不是线程安全的，在多线程的环境下，默认情况下，多个线程将会共享一个session。
假设A线程正在使用session处理数据库，B线程已经完成，把session给close了，那么此时
A在使用session就会报错。那么如何避免这个问题呢？
可以考虑在这些线程之间共享session及其对象。但是应用程序需要确保正确的锁方案，以便多个线程不会同时
访问session或其状态。SQLAlchemy中的scoped_session就可以保证线程安全。
为每个线程维护一个会话，而不是将对象从一个Session复制到另一个Session，通常使用
Session.merge()方法将对象状态复制到一个不同session的新本地对象中

scoped_session 使用结论：
1.在同一线程中，有scoped_session的时候，返回的是同一个session
2.在多线程中，即使通过scoped_session创建Session，每个线程下的Session都是不一样的，每个线程
    都有一个属于自己的Session对象，这个对象只有在本线程下共享。
3.scoped_session只有在单线程下才能发挥作用，多线程下显得没有什么作用。
"""

# 声明映射
Base = declarative_base()
# 创建引擎
Engine = create_engine(url=CommonConfig.SQLALCHEMY_DATABASE_URI, echo=True, future=True)
session = scoped_session(sessionmaker(bind=Engine))()
metadata = MetaData()
insp = inspect(Engine)

